#ifndef __SPDF_OPT_H__
#define __SPDF_OPT_H__

#include "stdint.h"
#include "mytype.h"

/*******************************************************************************
**********************************路径命令**************************************
******************************************************************************** 
结束路径还有以下命令，不在一个一个写函数使用，需要时使用自定义命令
"S\n"			%路径绘制					《结束路径，返回页面描述》
"f\n"			%路径填充					《结束路径，返回页面描述》
"h\n"			%结束路径并重新开始 相当于 S + m
"B\n"			%填充并绘制路径，等同f和S同时绘制的效果
"s\n"			%绘制并关闭路径
"b\n"			%关闭，绘制，填充路径
"f*\n"			%奇偶原则填充路径,其余同f	《结束路径，返回页面描述》
"B*\n"			%奇偶原则填充路径,其余同B，  
"b*\n"			%奇偶原则填充路径,其余同b
"x y m\n"		%开始路径,					《标志路径开始》
"x y l\n"		%画线
"n w\n"			%设置线宽
"x y w h re\n"	%画方框路径					《标志路径开始》

"r g b RG\n"	%设置RGB颜色
"n G\n"			%设置灰度颜色

"q"				%状态压栈-描述闭合区间之外，包括颜色、线形、端点、节点、文字位置
"Q"				%状态出栈-描述闭合区间之外

"n j\n"			%线连接样式 n=0尖头 n=1圆头 n=2 平截面
"n J\n"			%线端口样式 n=0平头 n=1圆头 n=2 平头延申0.5线宽。 
"n M\n"			%斜切极限

**********************************虚线模式**************************************
"[] 0 d\n"		%实线模式
"[n] 0 d\n"		%虚线 n-on n-off   常用
"[n] m d\n"		%虚线 m-on n-off
"[m n] 0 d\n"	%虚线 m-on n-off   常用

********************************************************************************
**********************************文本命令**************************************
********************************************************************************
"BT\n"				%开始文本
"ET\n"				%结束文本
"/Fn n Tf\n"		%选择字体
"x y Td\n"			%移动位置
"(ASCII) Tj\n"		%显示文本
"<HEX> Tj\n"		%显示文本
"n Tr\n"			%文本渲染模式
"n g\n"				%文本灰度颜色
"r g b rg \n"		%文本rgb颜色
"n w\n"				% Tr=1时，勾勒线宽
"n Tc\n"			% 字符间距
"n Tw\n"			% 字间距
"n Tz\n"			% 水平缩放 /100
"n TL\n"			% 行间距
"n Ts\n"			% 上升量

************************************字体****************************************
"Courier",
"Courier-Bold",
"Courier-Oblique",
"Courier-BoldOblique",
"Helvetica",
"Helvetica-Bold",
"Helvetica-Oblique",
"Helvetica-BoldOblique",
"Times-Roman",
"Times-Bold",
"Times-Italic",
"Times-BoldItalic",
"Symbol",
"ZapfDingbats",
"SimSun"

*****************************************************************************/

/*****************************************************************************
* @brief   函数映射
*****************************************************************************/
#define spdf_sprintf        sprintf

/*****************************************************************************
* @brief   错误类型
*****************************************************************************/
#define   SPDF_OK                           0
#define   SPDF_FAILED                       1
#define   SPDF_TRUE                         1
#define   SPDF_FALSE                        0
#define   SPDF_NOERROR                      0

#define   SPDF_INVALID_OBJECT               0x1033
#define   SPDF_INVALID_IMAGE                0x1030
#define   SPDF_INVALID_COLOR_SPACE          0x1020
#define   SPDF_INVALID_IMAGE_WIDTH          0x1031
#define   SPDF_PAGE_INVALID_SIZE			0x1054
#define   SPDF_INVALID_DOCUMENT             0x1025
#define   SPDF_PAGE_INVALID_FONT            0x104F

/*----- font state -------------------------------------*/
#define   SPDF_FONT_INVALID                 0x00FF
#define   SPDF_FONT_COURIER                 0x0000
#define   SPDF_FONT_COURIER_B               0x0001
#define   SPDF_FONT_COURIER_O               0x0002
#define   SPDF_FONT_COURIER_OB              0x0003
#define   SPDF_FONT_HELVETICA               0x0004
#define   SPDF_FONT_HELVETICA_B             0x0005
#define   SPDF_FONT_HELVETICA_O             0x0006
#define   SPDF_FONT_HELVETICA_BO            0x0007
#define   SPDF_FONT_TIMES_R                 0x0008
#define   SPDF_FONT_TIMES_B                 0x0009
#define   SPDF_FONT_TIMES_I                 0x000A
#define   SPDF_FONT_TIMES_BI                0x000B
#define   SPDF_FONT_SYMBOL                  0x000C
#define   SPDF_FONT_ZAP                     0x000D

/*----- Graphis mode -----------------------------------*/
#define   SPDF_GMODE_PAGE_DESCRIPTION       0x0001
#define   SPDF_GMODE_PATH_OBJECT            0x0002
#define   SPDF_GMODE_TEXT_OBJECT            0x0004
#define   SPDF_GMODE_CLIPPING_PATH          0x0008
#define   SPDF_GMODE_SHADING                0x0010
#define   SPDF_GMODE_INLINE_IMAGE           0x0020
#define   SPDF_GMODE_EXTERNAL_OBJECT        0x0040
#define   SPDF_GMODE_INVALID                0x0080
#define   SPDF_GMODE_OVER                   0x0100



/*****************************************************************************
* @brief   数据结构
*****************************************************************************/
typedef enum
{
    SPDF_CS_DEVICE_GRAY = 0,
    SPDF_CS_DEVICE_RGB,
    SPDF_CS_DEVICE_CMYK,
    SPDF_CS_CAL_GRAY,
    SPDF_CS_CAL_RGB,
    SPDF_CS_LAB,
    SPDF_CS_ICC_BASED,
    SPDF_CS_SEPARATION,
    SPDF_CS_DEVICE_N,
    SPDF_CS_INDEXED,
    SPDF_CS_PATTERN,
    SPDF_CS_EOF
}SPDF_ColorSpace;

typedef enum 
{
    SPDF_OBJ_INFO = 0,
    SPDF_OBJ_STREAM,
    SPDF_OBJ_FONT,
    SPDF_OBJ_PAGE,
    SPDF_OBJ_CATALOG,
    SPDF_OBJ_PAGES,
    SPDF_OBJ_IMAGE,
    SPDF_OBJ_EOF
}SPDF_ObjType;

typedef enum
{
	SPDF_PAGE_HEIGHT = 0,
	SPDF_PAGE_WIDTH,
	SPDF_PAGE_CTX_LENGTH,
	SPDF_PAGE_GMODE,
	SPDF_PAGE_FONTTYPE,
	SPDF_PAGE_FONTSIZE,
	SPDF_PAGE_EOF
}SPDF_PageAttr;

typedef enum
{
	SPDF_IMAGE_HEIGHT = 0,
	SPDF_IMAGE_WIDTH,
	SPDF_IMAGE_BITS,
	SPDF_IMAGE_COLORSPACE,
	SPDF_IMAGE_LENGTH,
	SPDF_IMAGE_ADDR,
	SPDF_IMAGE_OWNER,
	SPDF_IMAGE_NUMBER,
	SPDF_IMAGE_EOF
}SPDF_ImageAttr;

typedef struct
{
	SPDF_ObjType type;
	uu16 offset;
	uu16 number;
	int attr[10];
	void *doc;
}SPDF_Obj;


typedef struct
{
	SPDF_Obj *obj;
	int offset;
	uu16 pagesNumber;
	uu16 objNumber;
	uu16 imageNumber;
	uu16 obj_len_max;
	uu32 error;
	
	// buffer
	char buf[512];
	
	// file
	struct {
		uint16_t file_buff_index;
		uint16_t file_buff_size;
		uint8_t *file_buff;
		int (*file_disk_out)(uint8_t *buff, int len);
	} fil;
}SPDF_Doc_Rec;

typedef SPDF_Doc_Rec * SPDF_Doc;
typedef SPDF_Obj * SPDF_Page;
typedef SPDF_Obj * SPDF_Image;
extern const char *font_list[];

/*******************************************************************************
* @brief   API 基本操作
*******************************************************************************/
const char * spdf_get_version(void);

/*******************************************************************************
* @brief   创建 PDF。 创建过程按照下列API顺序
*******************************************************************************/
SPDF_Doc spdf_init(SPDF_Doc pdf, SPDF_Obj * pdf_obj, uu16 obj_len);
void spdf_disk_out_link(SPDF_Doc pdf, int (*disk_out)(uint8_t *buff, int len));
void spdf_disk_buff_set(SPDF_Doc pdf, uint8_t *buff, int len);	// 设置存盘文件缓存
SPDF_Doc spdf_create(SPDF_Doc pdf_doc);

/*******************************************************************************
* @brief   自定义指令
*******************************************************************************/
// 自定义输出 - 需保证合法性
void spdf_custom(SPDF_Page page, const char *cmd);

// 自定义输出 - 带一个参数, 需保证合法性
void spdf_custom_with_par(
	SPDF_Page page, 
	const char *cmd, 
	ii32 par, 
	uu8 ip_n);

// 自定义输出 - 需保证合法性 - 含参数列表
#define SPDF_CMD_NoExe		0x01
#define SPDF_CMD_End		0x02
#define SPDF_CMD_NoNum		0x10
#define SPDF_CMD_TFore		0x20
typedef struct
{
	const char * text;
	ii16 val;
	uu8 ip_n;
	// bit0-执行
	// bit1-结束
	// bit4-数据段跳过
	// bit5-0文本在后，1文本在前
	uu8 attr;	   
} spdf_custom_par_type;

// 列表定义
void spdf_custom_cfg(
	spdf_custom_par_type *par, 
	const char * text,
	ii16 val,
	uu8 ip_n,
	uu8 attr);

void spdf_custom_exe( SPDF_Page page, spdf_custom_par_type *par, ii8 max);

// 检测文件是否合法
ii8 spdf_has_doc(SPDF_Doc pdf);

// 添加新页
SPDF_Page spdf_add_page(SPDF_Doc pdf);

// 文件保存
uu32 spdf_save(SPDF_Doc pdf,const char *file_name);

// 页面检测
uu32 spdf_page_check(SPDF_Page page, uu32 mode);

// 页面保存
uu32 spdf_page_save(SPDF_Page page);

// 获取页面高度
uu16 spdf_page_get_height(SPDF_Page page);

// 获取页面宽度
uu16 spdf_page_get_width(SPDF_Page page);

// 设置页面高度
uu32 spdf_page_set_height(SPDF_Page page, uu16 value);

// 设置页面宽度
uu32 spdf_page_set_width(SPDF_Page page, uu16 value);

// 状态栈 仅空闲或文本状态可用
uu32 spdf_page_push(SPDF_Page page);
uu32 spdf_page_pop(SPDF_Page page);

/*******************************************************************************
* @brief   API 文本操作
*******************************************************************************/
// 设置字体
uu32 spdf_page_set_font(SPDF_Page page, const char *font_name, uu8 size);

// 设置文本rgb颜色
uu32 spdf_page_set_text_rgb(SPDF_Page page, uu8 r, uu8 g, uu8 b);

// 设置文本灰度颜色
uu32 spdf_page_set_text_gray(SPDF_Page page, uu8 gray);

// 设置文本渲染模式, 0-7参见手册，wide仅对mode=1有效, wide含两位小数
uu32 spdf_page_set_text_mode(SPDF_Page page, uu8 mode, uu16 wide);

// 文本开始
uu32 spdf_page_begin_text(SPDF_Page page);

// 文本结束
uu32 spdf_page_end_text(SPDF_Page page);

// 显示文本
uu32 spdf_page_show_text(SPDF_Page page, const char *text);

// 显示文本 - 状态检测 - 使用快速输出前需要先检测
uu32 spdf_page_show_text_check(SPDF_Page page);

// 显示文本 - 如果确保是纯ascii，快速输出，ascii码明文
// 特殊字符 ( ) \ 前须加一个 \号
uu32 spdf_page_show_text_ascii(SPDF_Page page, const char *text);

// 显示文本 - GBK方式，快速输出， 十六进制码
uu32 spdf_page_show_text_gbk(SPDF_Page page, const char *text);

// 文本坐标移动
uu32 spdf_page_move_text_pos(SPDF_Page page, ii32 x, ii32 y);
// 文本坐标移动 - 含一位小数
uu32 spdf_page_p1_move_text_pos(SPDF_Page page, ii32 x, ii32 y);

// 显示文本，含坐标移动
uu32 spdf_page_text_out(
	SPDF_Page page, 
	uu16 x, uu16 y,
	const char *text);

/*******************************************************************************
* @brief   API 基础图形
*******************************************************************************/
// 设置画笔颜色-用于划线
uu32 spdf_page_set_stroke_rgb( SPDF_Page page, uu8 r, uu8 g, uu8 b);

// 灰度颜色设置
uu32 spdf_page_set_stroke_gray(SPDF_Page page, uu8 gray);

// 虚线 开关
uu32 spdf_page_dash_off(SPDF_Page page);	
uu32 spdf_page_dash_on(SPDF_Page page, ii16 on, ii16 off, uu8 ip_n);

// 线端点节点模式 0平头 1圆头 2平头延申0.5w
uu32 spdf_page_endpoint_mode(SPDF_Page page, uu8 mode); // 端点模式	
uu32 spdf_page_node_mode(SPDF_Page page, uu8 mode);	// 节点模式

// 划线，路径 绘制  相当于自定义命令 “S\n”
uu32 spdf_page_stroke(SPDF_Page page);

// 划线，填充路径闭合区间 相当于自定义命令 “f\n”
uu32 spdf_page_stroke_fill(SPDF_Page page);

// 设置路径当前位置坐标
uu32 spdf_page_move_to (SPDF_Page page, ii32 x, ii32 y, uu8  ip_n);

// 设置路径当前位置坐标, 含一位小数
uu32 spdf_page_p1_move_to (SPDF_Page page, ii32 x, ii32 y);

// 画线路径 目标位置 并移动当前位置
uu32 spdf_page_line_to (SPDF_Page page, ii32 x, ii32 y, uu8  ip_n);

// 画线路径 目标位置 并移动当前位置, 含一位小数
uu32 spdf_page_p1_line_to (SPDF_Page page, ii32 x, ii32 y);

// 划曲线路径到目标位置 - 三次贝尔曲线 - 并移动当前位置到x3,y3
uu32 spdf_page_curve123_to(
	SPDF_Page page,
	ii32 x1, ii32 y1,
	ii32 x2, ii32 y2,
	ii32 x3, ii32 y3,
	uu8  ip_n);

uu32 spdf_page_curve23_to(
	SPDF_Page page,
	ii32 x2, ii32 y2,
	ii32 x3, ii32 y3,
	uu8  ip_n);	
							   
uu32 spdf_page_curve13_to(
	SPDF_Page page,
	ii32 x1, ii32 y1,
	ii32 x3, ii32 y3,
	uu8  ip_n);						  

// 画圆路径
uu32 spdf_page_cycle(
	SPDF_Page page,
	ii32 x, ii32 y,
	ii32 c,
	uu8  ip_n);

// 画方框 路径
uu32 spdf_page_rectangle(
	SPDF_Page page,
	ii32 x, ii32 y,
	ii32 width, ii32 height,
	uu8  ip_n);	

// 设置线宽
uu32 spdf_page_set_line_width(SPDF_Page page, uu16 line_width);

// kog
uu32 spdf_page_close_path_stroke(SPDF_Page page);

/*******************************************************************************
* @brief   API 图像
*******************************************************************************/
// 画图
uu32 spdf_page_draw_img(SPDF_Page page,
	SPDF_Image image,
	uu16 x, uu16 y,
	uu16 width, uu16 height);

// 画图
SPDF_Image spdf_page_draw_img_from_file(SPDF_Doc pdf,
	const char *filename,
	uu32 width, uu32 height,
	SPDF_ColorSpace color_space);

// 画图
SPDF_Image spdf_page_draw_img_from_mem(SPDF_Doc pdf,
	const uu8 *buf,
	uu32 width, uu32 height,
	SPDF_ColorSpace color_space,
	uu32 bits_per_component);

/*****************************************************************************
* @brief   颜色转换
* @return  gray
*****************************************************************************/
uu8 spdf_rgb_to_gray(uu8 *rgb);

// 输入 RGB 比例(0-100) 和 目标灰度值(0-100)
uu8 spdf_gry_to_rgb(uu8 *rgb, uu8 gray);

#endif
